home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / mortpay.com / MORTPAY.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1989-06-10  |  8.6 KB  |  280 lines

  1. program MortgagePaymentSchedule;{MORTPAY.PAS}
  2.  
  3.             {Assumes a mortgage is to be paid off in equal monthly payments over a
  4. specified number of months and based on a constant annual interest rate, one
  5. twelth of which is charged each month on the remaining balance.  While this
  6. program is written for a constant interest rate and number of payments, the
  7. balance in any month, together with a new interest rate and a new monthly
  8. payment, can be used to compute a new mortgage schedule for variable rate
  9. mortgages.}
  10.  
  11.             {Note the const values in procedure InputData which are used to
  12. validate input data. They may be changed to more restrictive or to less
  13. restrictive values if more appropriate for the user.  I suggest retaining
  14. the LoInt value to ensure that the annual interest is entered as a percent
  15. instead of as a decimal fraction less than 1.0.  The MaxBal and MaxPay are
  16. related in a general way; if one is changed it may be prudent to change the
  17. other.  Note, however, that it is possible to exceed MaxPay by entering a
  18. large MaxBal and a small number of months to pay.  Similiarly, it is
  19. possible to exceed MaxMon by entering a large MaxBal and a small monthly
  20. payment.}
  21.  
  22. uses
  23.     crt,printer;
  24.  
  25. const
  26.     D9='---------';         {9 dashes}
  27.     D11='-----------';      {11 dashes}
  28.     Bal0=10e-3;             {Close approximation to zero}
  29. var
  30.     Num,BegMon,Y,k:integer;
  31.             {Num is the number of payments of number of months.  BegMon is the
  32. first month of the calendar year is which payment is due.  Y is the current
  33. calendar year.  k is an index for counting calendar years.}
  34.  
  35.     Bal,AIR,Pay,Interest,Prin:real;
  36.             {Bal is the unpaid balance of the principal.  AIR is the annual
  37. interest rate in %.  Interest is interest calculated monthly on unpaid
  38. balance.  Prin is the amount of principal which is deducted from the balance
  39. is the given month and is equal to the monthly payment minus the interest
  40. for that month.}
  41.  
  42.     PrtChoice,ch:Char;
  43.             {PrtChoice determines whether to send output to printer.  ch is a
  44. dummy variable.}
  45.  
  46.     Abort:boolean;
  47.             {Abort is a flag to determine whether to terminate program before
  48. running.}
  49.  
  50.  
  51. procedure DisplayDashLine;  {Inserts dashed lines in display}
  52.  
  53.   begin
  54.         writeln(D11:25,D9:10,D9:10,D9:10,D9:10)
  55.     end;
  56.  
  57.  
  58. procedure PrintDashLine;  {Inserts dashed lines in print out}
  59.  
  60.   begin
  61.         writeln(Lst,D11:25,D9:10,D9:10,D9:10,D9:10)
  62.     end;
  63.  
  64.  
  65. procedure InputData;
  66.  
  67.     const               {Ranges of values to assist in validating input}
  68.     MinBal=10.0;
  69.         MaxBal=250000.0;
  70.         LoInt=1.0;        {Lowest annual interest rate in %}
  71.         HiInt=20.0;       {Highest annual interest rate in %}
  72.     MinPay=1.0;
  73.         MaxPay=3000.0;    {Max monthly payment}
  74.         MinMon=1;
  75.         MaxMon=30*12;     {Max number of months of loan}
  76.         LoY=1950;           {Earliest beginning year}
  77.         HiY=2020;           {Latest beginning year}
  78.  
  79.         BadEnt='Invalid entry; please try again.';
  80.  
  81.     var
  82.         Choice:char;
  83.             {Choice determines whether monthly payment of number of
  84. payments/months are entered.}
  85.  
  86.     begin
  87.         Bal:=0;AIR:=0;Pay:=0;Num:=0;BegMon:=0;Y:=1900;          {Initialization}
  88.         Choice:='x';                                            {initialization}
  89.  
  90.         writeln;
  91.         writeln('To terminate program during data input, enter -1.');
  92.     writeln;
  93.  
  94.         Abort:=false;
  95.     while not((Bal>=MinBal) and (Bal<=MaxBal)) and (Abort=false) do
  96.     begin
  97.             write('Enter balance owed:  ':55);
  98.       readln(Bal);
  99.             if Bal=-1 then Abort:=true
  100.       else if not((Bal>=MinBal) and (Bal<=MaxBal)) then
  101.         writeln(BadEnt)
  102.         end;  {while do re Bal}
  103.  
  104.         while not((AIR>=LoInt) and (AIR<=HiInt)) and (Abort=false) do
  105.     begin
  106.             write('Enter annual interest rate in percent:  ':55);
  107.       readln(AIR);
  108.       if AIR=-1 then Abort:=true
  109.       else if not((AIR>=LoInt) and (AIR<=HiInt)) then writeln(BadEnt)
  110.         end;  {while do re AIR}
  111.  
  112.         while ((Choice<>'p') and (Choice<>'m')) and (Abort=false) do
  113.         begin
  114.             writeln;
  115.             writeln('You may enter either the monthly payment');
  116.             writeln('    or the number of months to pay.');
  117.             write('Enter p (for payment) or m (for months):  ');
  118.             readln(Choice);
  119.             writeln;
  120.         end;  {while do re Choice}
  121.  
  122.         if Choice='p' then
  123.         begin
  124.             while not((Pay>=MinPay) and (Pay<=MaxPay)) and (Abort=false) do
  125.             begin
  126.                 write('Enter monthly payment:  ':55);
  127.                 readln(Pay);
  128.                 if Pay=-1 then Abort:=true
  129.                 else if not((Pay>=MinPay) and (Pay<=MaxPay)) then writeln(BadEnt)
  130.             end;  {while do re Pay}
  131.         end  {if Choice}
  132.  
  133.         else
  134.         begin
  135.             while not((Num>=MinMon) and (Num<=MaxMon)) and (Abort=false) do
  136.             begin
  137.                 write('Enter number of months to pay:  ':55);
  138.                 readln(Num);
  139.                 if Num=-1 then Abort:=true
  140.                 else if not((Num>=MinMon) and (Num<=MaxMon)) then writeln(BadEnt)
  141.                 else Pay:=int(Bal*AIR/12/(1-exp(-Num*ln(1+AIR/1200)))+1)/100.0
  142.             end;  {while do re Num}
  143.         end;  {else}
  144.  
  145.         while not((BegMon>0) and (BegMon<13)) and (Abort=false) do
  146.     begin
  147.             write('Enter first month (1 to 12) in which payment due:  ':55);
  148.       readln(BegMon);
  149.       if BegMon=-1 then Abort:=true
  150.       else if not((BegMon>0) and (BegMon<13)) then writeln(BadEnt)
  151.     end; {while do re BegMon}
  152.  
  153.         while not((Y>=LoY) and (Y<=HiY)) and (Abort=false) do
  154.       begin
  155.             write('Enter first year in which payment is due:  ':55);
  156.       readln(Y);
  157.       if Y=-1 then Abort:=true
  158.       else if not((Y>=LoY) and (Y<=HiY)) then writeln(BadEnt)
  159.         end;  {while do re Y}
  160.  
  161.         write('Print hard copy (y/n)?  ':55);
  162.         readln(PrtChoice);
  163.     end;  {procedure InputData}
  164.  
  165.  
  166. procedure DisplayHeading;
  167.  
  168.   begin
  169.         writeln; writeln; writeln;
  170.         writeln('MORTGAGE PAYMENT SCHEDULE':53);
  171.         writeln('(':27,AIR:4:2,'% Annual Interest Rate)');
  172.         writeln;
  173.         writeln('Payment':35,'Interest':10,'Principal':10,
  174.                 'Balance':10);
  175.         DisplayDashLine;
  176.         writeln(Bal:65:2)
  177.     end;
  178.  
  179.  
  180. procedure PrintHeading; {Includes printing of current balance owed.}
  181.  
  182.   begin
  183.         write(Lst,#10#10#10#10#10);          {to provide 5 vertical spaces}
  184.         writeln(Lst,'MORTGAGE PAYMENT SCHEDULE':53);
  185.         writeln(Lst,'(':27,AIR:4:2,'% Annual Interest Rate)':23);
  186.         writeln(Lst);
  187.         writeln(Lst,'Payment':35,'Interest':10,'Principal':10,
  188.                 'Balance':10);
  189.         PrintDashLine;
  190.     writeln(Lst,Bal:65:2)
  191.     end;
  192.  
  193.  
  194. procedure CalendarYearResults;
  195.  
  196.   const
  197.         Mon:array[1..12] of string[3]=('Jan','Feb','Mar','Apr','May',
  198.              'Jun','Jul','Aug','Sep','Oct','Nov','Dec');
  199.  
  200.   type
  201.     Month=string[3];
  202.  
  203.   var
  204.     CurMon:Month;
  205.         j:1..13;                           {Counter for month of calendar year.}
  206.     PayYTD,IntYTD,PrinYTD:real;
  207.  
  208.   begin
  209.         j:=BegMon;                                              {Initialization}
  210.         PayYTD:=0;IntYTD:=0;PrinYTD:=0;                         {Initialization}
  211.         Bal:=int(Bal*100.0+0.5)/100.0;      {To ensure Bal begins on whole cent}
  212.  
  213.         while (j>=1) and (j<=12) and (Bal>Bal0) do
  214.     begin
  215.       Interest:=int(Bal*AIR/12+0.5)/100;
  216.       Prin:=Pay-Interest;
  217.       if Prin>Bal then
  218.       begin
  219.         Prin:=Bal;
  220.         Pay:=Interest+Bal
  221.             end;  {if Prin>Bal}
  222.       Bal:=Bal-Prin;
  223.       CurMon:=Mon[j];
  224.             writeln(CurMon:17,Pay:18:2,Interest:10:2,Prin:10:2,Bal:10:2);
  225.             if (PrtChoice='y') or (PrtChoice='Y') then
  226.                 writeln(Lst,CurMon:17,Pay:18:2,Interest:10:2,Prin:10:2,Bal:10:2);
  227.             PayYTD:=PayYTD+Pay;
  228.       IntYTD:=IntYTD+Interest;
  229.       PrinYTD:=PrinYTD+Prin;
  230.       j:=j+1
  231.         end;  {while do re j}
  232.         DisplayDashLine;
  233.         writeln(Y:18,'Totals':7,PayYTD:10:2,IntYTD:10:2,PrinYTD:10:2,Bal:10:2);
  234.         writeln;
  235.         if (PrtChoice='y') or (PrtChoice='Y') then
  236.         begin
  237.             PrintDashLine;
  238.             writeln(Lst,Y:18,'Totals':7,PayYTD:10:2,IntYTD:10:2,PrinYTD:10:2,
  239.                     Bal:10:2);
  240.             writeln(Lst);
  241.         end  {if PrtChoice}
  242.   end; {procedure CalendarYearResults}
  243.  
  244.  
  245. begin {program block}
  246.   InputData;
  247.   if Abort=false then
  248.   begin
  249.         DisplayHeading;
  250.         if (PrtChoice='y') or (PrtChoice='Y') then PrintHeading;
  251.         k:=0;
  252.         while Bal>Bal0 do
  253.         begin
  254.             CalendarYearResults;
  255.             BegMon:=1;Y:=Y+1;k:=k+1;
  256.             if (PrtChoice='y') or (PrtChoice='Y') then
  257.                 if (k mod 3=0) and (Bal>Bal0) then
  258.                 begin
  259.                     write(Lst,#12);                                  {goto a new page}
  260.                     PrintHeading;
  261.                 end;  {if k mod 3=0}
  262.             if (PrtChoice<>'y') and (PrtChoice<>'Y') and (Bal>Bal0) then
  263.             begin
  264.                 writeln('Press any key to continue...');
  265.                 ch:=ReadKey;
  266.                 writeln;writeln;writeln;
  267.                 DisplayHeading;
  268.             end  {if PrtChoice<>}
  269.         end;  {while Bal>Bal0 do}
  270.         if (PrtChoice='y') or (PrtChoice='Y') and (Bal<Bal0) then
  271.             write(Lst,#12);
  272.     end  {if Abort=false}
  273.   else
  274.     begin
  275.         writeln;
  276.         writeln('Program terminated before running.');
  277.         writeln;
  278.     end
  279. end.  {program block}
  280.